package com.byapp.fast.modules.order.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.byapp.fast.common.converter.*;
import com.byapp.fast.common.enums.*;
import com.byapp.fast.common.exception.BYException;
import com.byapp.fast.common.utils.*;
import com.byapp.fast.modules.contract.biz.BusinessBiz;
import com.byapp.fast.modules.contract.biz.RetBiz;
import com.byapp.fast.modules.contract.dto.CallBackBetDTO;
import com.byapp.fast.modules.contract.dto.CallBackEthDTO;
import com.byapp.fast.modules.contract.dto.PayDTO;
import com.byapp.fast.modules.contract.service.ContractService;
import com.byapp.fast.modules.match.entity.MatchOddsEntity;
import com.byapp.fast.modules.match.entity.MatchRefEntity;
import com.byapp.fast.modules.match.service.MatchService;
import com.byapp.fast.modules.order.dao.OrderDao;
import com.byapp.fast.modules.order.dto.OrderDataDTO;
import com.byapp.fast.modules.order.dto.OrderItemDTO;
import com.byapp.fast.modules.order.entity.ItemContentEntity;
import com.byapp.fast.modules.order.entity.OrderEntity;
import com.byapp.fast.modules.order.entity.OrderItemEntity;
import com.byapp.fast.modules.order.entity.OrderItemExtEntity;
import com.byapp.fast.modules.order.service.ItemContentService;
import com.byapp.fast.modules.order.service.OrderItemExtService;
import com.byapp.fast.modules.order.service.OrderItemService;
import com.byapp.fast.modules.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("orderService")
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    @Autowired
    private ItemContentService itemContentService;

    @Autowired
    private OrderItemExtService orderItemExtService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private ContractService contractService;

    @Autowired
    private MatchService matchService;

    @Autowired
    private BusinessBiz businessBiz;

    @Override
    @Transactional
    public void createEthOrder(CallBackEthDTO callBackEthDTO) {

        CallBackBetDTO callBackBetDTO = callBackEthDTO.getCallBackBetDTO();

        // 获取订单参数
        String orderId = UUIDGenerator.getUUID();
        String txHash = callBackEthDTO.getTxHash();
        String userId = callBackBetDTO.getBetAddress();
        String betId = callBackBetDTO.getBetId();
        String roomId = callBackBetDTO.getRoomId();
        String symbol = callBackBetDTO.getSymbol();
        String playId = callBackBetDTO.getPlayCode();
        String matchId = callBackBetDTO.getLid();
        String oddsId = callBackBetDTO.getPlayId();
        String handicap = callBackBetDTO.getHandicap();
        String odds = callBackBetDTO.getBetOdds();
        double buyMoney = Double.parseDouble(callBackBetDTO.getBetMoney());

        // 添加订单数据
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderId(orderId);
        orderEntity.setBuyMoney(buyMoney);
        orderEntity.setPayStatus(PayStatusEnum.PAY_SUCCESS.getCode());
        orderEntity.setOrderStatus(OrderStatusEnum.ORDER_SUCCESS.getCode());
        orderEntity.setBuyUser(userId);
        orderEntity.setPayType(symbol);
        log.info("【生成订单】添加订单，orderEntity={}", JsonUtils.toJson(orderEntity));
        boolean orderFlag = this.insert(orderEntity);
        if (!orderFlag) {
            log.error("【生成订单】添加订单失败，orderEntity={}", JsonUtils.toJson(orderEntity));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单数据
        OrderItemEntity orderItemEntity = new OrderItemEntity();


        // 获取赔率
        String[] typeItems = PlayIdUtils.getTypeItems(playId);
        String lotId = "701";
        int buyType = Integer.parseInt(typeItems[0]);
        int playType = Integer.parseInt(typeItems[1]);

        orderItemEntity.setItemId(UUIDGenerator.getUUID());
        orderItemEntity.setOrderId(orderId);
        orderItemEntity.setUserId(userId);
        orderItemEntity.setItemContent(JsonUtils.toNormalJson(callBackBetDTO));
        orderItemEntity.setBuyType(buyType);
        orderItemEntity.setPlayType(playType);
        orderItemEntity.setPlayId(playId);
        orderItemEntity.setLotId(lotId);
        orderItemEntity.setItemMoney(buyMoney);
        orderItemEntity.setPayType(symbol);
        orderItemEntity.setBalanceMatchId(matchId);
        orderItemEntity.setSrcCode("eth");
        orderItemEntity.setSportType(EnumUtils.getByCode(Integer.parseInt(lotId), LotIdEnum.class).getSport());
        orderItemEntity.setTxhash(txHash);
        orderItemEntity.setBetId(betId);
        orderItemEntity.setRoomId(roomId);
        orderItemEntity.setOddsId(Long.valueOf(oddsId));
        orderItemEntity.setOdds(odds);
        orderItemEntity.setHandicap(handicap);
        orderItemEntity.setItemStatus(ItemStatusEnum.ITEM_SUCCESS.getCode());

        MatchRefEntity matchRefEntity = matchService.queryById(matchId);
        orderItemEntity
                .setHomeTeamName(matchRefEntity.getHomeTeamName())
                .setAwayTeamName(matchRefEntity.getAwayTeamName())
                .setMatchTime(matchRefEntity.getMatchTime())
                .setLeagueName(matchRefEntity.getLeagueName());

        log.info("【生成订单】添加投注单，orderItemEntity={}", JsonUtils.toJson(orderItemEntity));
        boolean orderItemFlag = orderItemService.insert(orderItemEntity);
        if (!orderItemFlag) {
            log.error("【生成订单】添加投注单失败，orderItemEntity={}", JsonUtils.toJson(orderItemEntity));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单扩展数据
        OrderItemExtEntity orderItemExtEntity = OrderItemExtConverter.mapToTarget(orderItemEntity);
        log.info("【生成订单】添加投注单扩展，orderItemExtEntity={}", JsonUtils.toJson(orderItemExtEntity));
        boolean orderItemExtFlag = orderItemExtService.insert(orderItemExtEntity);
        if (!orderItemExtFlag) {
            log.error("【生成订单】添加投注单扩展失败，orderItemExtEntity={}", JsonUtils.toJson(orderItemExtEntity));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单详情数据
        ItemContentEntity itemContentEntity = ItemContentConverter.mapToTarget(orderItemEntity);
        log.info("【生成订单】添加投注单内容，itemContentList={}", JsonUtils.toJson(itemContentEntity));
        boolean itemContentFlag = itemContentService.insert(itemContentEntity);
        if (!itemContentFlag) {
            log.error("【生成订单】添加投注单内容失败，itemContentEntity={}", JsonUtils.toJson(itemContentEntity));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }
    }

    @Override
    @Transactional
    public String createWebOrder(OrderDataDTO orderDataDTO) {

        // 获取主订单参数
        String orderId = UUIDGenerator.getUUID();
        String serialType = orderDataDTO.getSerialType();
        String lotId = orderDataDTO.getLotId();
        String payType = orderDataDTO.getPayType();
        String srcCode = orderDataDTO.getSrcCode();

        // 添加订单数据
        OrderEntity orderEntity = OrderDataDTOConverter.create(orderDataDTO);
        orderEntity.setOrderId(orderId);
        log.info("【生成订单】添加订单，orderEntity={}", JsonUtils.toJson(orderEntity));
        boolean orderFlag = this.insert(orderEntity);
        if (!orderFlag) {
            log.error("【生成订单】添加订单失败，orderEntity={}", JsonUtils.toJson(orderEntity));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单数据
        List<OrderItemDTO> itemsList = orderDataDTO.getItemsList();
        List<OrderItemEntity> orderItemList = OrderItemDTOConverter.mapToTarget(itemsList);
        // 设置全局属性
        orderItemList.forEach(orderItemEntity -> {
                    String matchId = orderItemEntity.getBalanceMatchId();
                    String playId = orderItemEntity.getPlayId();
                    String handicap = orderItemEntity.getHandicap();
                    MatchRefEntity matchRefEntity = matchService.queryById(matchId);
                    Map<String, Object> map = new HashMap<>();
                    map.put("MATCH_ID", matchId);
                    map.put("PLAY_ID", playId);
                    map.put("HANDICAP", handicap);
                    map.put("ODDS_PHASE", 2);
                    MatchOddsEntity matchOddsEntity = matchService.queryMatchOdds(map);
                    orderItemEntity
                            .setLotId(lotId)
                            .setPayType(payType)
                            .setPassType(serialType)
                            .setOrderId(orderId)
                            .setSrcCode(srcCode)
                            .setSportType(EnumUtils.getByCode(Integer.parseInt(lotId), LotIdEnum.class).getSport())
                            .setItemContent(JsonUtils.toNormalJson(itemsList))
                            .setHomeTeamName(matchRefEntity.getHomeTeamName())
                            .setAwayTeamName(matchRefEntity.getAwayTeamName())
                            .setMatchTime(matchRefEntity.getMatchTime())
                            .setOddsId(matchOddsEntity.getId())
                            .setLeagueName(matchRefEntity.getLeagueName());
                }
        );
        log.info("【生成订单】添加投注单，orderItemList={}", JsonUtils.toJson(orderItemList));
        boolean orderItemFlag = orderItemService.insertBatch(orderItemList);
        if (!orderItemFlag) {
            log.error("【生成订单】添加投注单失败，orderItemEntityList={}", JsonUtils.toJson(orderItemList));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单扩展数据
        List<OrderItemExtEntity> orderItemExtList = OrderItemExtConverter.mapToTarget(orderItemList);
        log.info("【生成订单】添加投注单扩展，orderItemExtList={}", JsonUtils.toJson(orderItemExtList));
        boolean orderItemExtFlag = orderItemExtService.insertBatch(orderItemExtList);
        if (!orderItemExtFlag) {
            log.error("【生成订单】添加投注单扩展失败，orderItemExtEntities={}", JsonUtils.toJson(orderItemExtList));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 添加投注单详情数据
        List<ItemContentEntity> itemContentList = ItemContentConverter.mapToTarget(orderItemList);
        log.info("【生成订单】添加投注单内容，itemContentList={}", JsonUtils.toJson(itemContentList));
        boolean itemContentFlag = itemContentService.insertBatch(itemContentList);
        if (!itemContentFlag) {
            log.error("【生成订单】添加投注单内容失败，itemContentList={}", JsonUtils.toJson(itemContentList));
            throw new BYException(ResultEnum.ILLEGAL_PARAM);
        }

        // 调用合约订单接口
        RetBiz retBiz = contractService.callCreateContractTx(orderItemList);

        // 构造唤起支付参数
        PayDTO payDTO = PayDTOConverter.create(businessBiz, orderDataDTO, orderId, retBiz.getResult().toString());
        Map<String, Object> map = SignUtils.transBean2Map(payDTO);
        // 构造签名
        String signTemp = SignUtils.generateURL(map) + "&dappkey=" + businessBiz.getDappkey();
        System.out.println(signTemp);
        String sign = SignUtils.encodeMD5(signTemp).toUpperCase();
        map.put("sign", sign);
        return JsonUtils.toNormalJson(map);
    }


}
